package com.atguigu.webflux.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebSession;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.util.Map;

/**
 * @author Jungle
 * @create 2024-01-13 11:03
 */
@Slf4j
@RequestMapping("/webflux")
@RestController
public class HelloController {





    @GetMapping("/hello")
    public String hello(@RequestParam(value = "key", required = false, defaultValue = "哈哈") String key,
                        ServerWebExchange exchange,
                        WebSession session,
                        HttpMethod method,
                        HttpEntity<String> entity,
                        @RequestBody String s,
                        FilePart file
    ) {
        // file.transferTo()  //零拷贝技术
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        Map<String, Object> aaa = session.getAttribute("aaa");
        // 请求方式
        String name = method.name();
        log.info("请求方式==>{}", name);
        String body = entity.getBody();
        log.info("请求体==>{}", body);
        session.getAttributes().put("aa", "nn");
        return "Hello World !!!===》" + key;
    }


    //现在推荐的方式
    // 1、 返回单个数据Mono:  Mono<Order> Order、User、String、Map
    // 2、 返回多个数据Flux:  Flux<Order> Order、User、String、Map
    // 3、配合Flux，完成SSE: server Send Event;服务端事件推送
    @GetMapping("/haha")
    public Mono<String> haha1() {
        return Mono.just(0).map(i -> 10 / i)
                .map(i -> "哈哈-" + i);
    }


    @GetMapping("/haha1")
    public ResponseEntity<String> haha() {
        return ResponseEntity.status(305)
                .header("aaa", "bbb")
                .contentType(MediaType.APPLICATION_CBOR)
                .body("aaaa");
    }

    @GetMapping("/hehe")
    public Flux<String> hehe1() {
        return Flux.just("hehe1", "hehe2");
    }


    /**
     * sse 测试  服务端推送
     */
    // @GetMapping(value = "/sse",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    // public Flux<String> sse() {
    //     return Flux.range(1, 10)
    //             .map(i -> "ha==>" + i)
    //             .delayElements(Duration.ofMillis(500));
    // }

    // SpringMVC以前怎么用，基本可以无缝切换。
    // 底层:需要自己开始编写响应式代码


    /**
     * 1、api
     */

    @GetMapping(value = "/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<String>> sseApi() {
        return Flux.range(1, 10)
                .map(i -> {
                    // 构建一个sse对象
                    return ServerSentEvent.builder("ha-" + i)
                            .id(i + "")
                            .comment("hei-" + i).event("haha")
                            .build();
                })
                .delayElements(Duration.ofMillis(500));
    }


}
